﻿Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Drawing.Drawing2D
Imports System.IO
Imports System.Runtime.InteropServices

Namespace System.Workflow.ComponentModel.Design
    Public Class ActivityDesignerTheme
        Inherits DesignerTheme
        ' Methods
        Public Sub New(ByVal theme As WorkflowTheme)
            MyBase.New(theme)
            Me.designerImagePath = String.Empty
            Me.foreColor = Color.Black
            Me.borderColor = Color.Black
            Me.backColorStart = Color.White
            Me.backColorEnd = Color.Empty
        End Sub

        Private Sub ApplySystemColors()
            Me.ForeColor = SystemColors.ControlText
            Me.BorderColor = SystemColors.ControlDark
            Me.BackColorStart = SystemColors.Control
            Me.BackColorEnd = SystemColors.ControlLight
        End Sub

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try 
                If (Not Me.designerImage Is Nothing) Then
                    Me.designerImage.Dispose
                    Me.designerImage = Nothing
                End If
                If (Not Me.foregroundPen Is Nothing) Then
                    Me.foregroundPen.Dispose
                    Me.foregroundPen = Nothing
                End If
                If (Not Me.foregroundBrush Is Nothing) Then
                    Me.foregroundBrush.Dispose
                    Me.foregroundBrush = Nothing
                End If
                If (Not Me.borderPen Is Nothing) Then
                    Me.borderPen.Dispose
                    Me.borderPen = Nothing
                End If
                If (Not Me.backgroundBrush Is Nothing) Then
                    Me.backgroundBrush.Dispose
                    Me.backgroundBrush = Nothing
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Function GetBackgroundBrush(ByVal rectangle As Rectangle) As Brush
            If ((Me.backgroundBrush Is Nothing) OrElse (Me.backgroundBrushRect <> rectangle)) Then
                If (Not Me.backgroundBrush Is Nothing) Then
                    Me.backgroundBrush.Dispose
                End If
                Me.backgroundBrushRect = rectangle
                If (Me.backColorStart = Me.backColorEnd) Then
                    Me.backgroundBrush = New SolidBrush(Me.backColorStart)
                Else
                    Me.backgroundBrush = New LinearGradientBrush(Me.backgroundBrushRect, Me.backColorStart, Me.backColorEnd, Me.backgroundStyle)
                End If
            End If
            Return Me.backgroundBrush
        End Function

        Friend Overrides Function GetPropertyValues(ByVal context As ITypeDescriptorContext) As ICollection
            Dim objArray As Object() = New Object(0  - 1) {}
            If String.Equals(context.PropertyDescriptor.Name, "BorderStyle", StringComparison.Ordinal) Then
                objArray = New Object() { DashStyle.Solid, DashStyle.Dash, DashStyle.DashDot, DashStyle.DashDotDot, DashStyle.Dot }
            End If
            Return objArray
        End Function

        Public Overrides Sub Initialize()
            MyBase.Initialize
            If MyBase.ContainingTheme.AmbientTheme.UseOperatingSystemSettings Then
                Me.ApplySystemColors
            End If
        End Sub

        Public Overrides Sub OnAmbientPropertyChanged(ByVal ambientProperty As AmbientProperty)
            If (ambientProperty = AmbientProperty.DesignerSize) Then
                Me.ForeColor = Me.foreColor
                Me.BorderColor = Me.borderColor
            ElseIf (ambientProperty = AmbientProperty.OperatingSystemSetting) Then
                Me.ApplySystemColors
            End If
        End Sub


        ' Properties
        <Editor(GetType(ColorPickerEditor), GetType(UITypeEditor)), SRCategory("BackgroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), DispId(6), SRDescription("BackColorEndDesc", "System.Workflow.ComponentModel.Design.DesignerResources"), TypeConverter(GetType(ColorPickerConverter))> _
        Public Overridable Property BackColorEnd As Color
            Get
                Return Me.backColorEnd
            End Get
            Set(ByVal value As Color)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                Me.backColorEnd = value
                If (Not Me.backgroundBrush Is Nothing) Then
                    Me.backgroundBrush.Dispose
                    Me.backgroundBrush = Nothing
                End If
            End Set
        End Property

        <SRCategory("BackgroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), TypeConverter(GetType(ColorPickerConverter)), Editor(GetType(ColorPickerEditor), GetType(UITypeEditor)), DispId(5), SRDescription("BackColorStartDesc", "System.Workflow.ComponentModel.Design.DesignerResources")> _
        Public Overridable Property BackColorStart As Color
            Get
                Return Me.backColorStart
            End Get
            Set(ByVal value As Color)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                Me.backColorStart = value
                If (Not Me.backgroundBrush Is Nothing) Then
                    Me.backgroundBrush.Dispose
                    Me.backgroundBrush = Nothing
                End If
            End Set
        End Property

        <SRCategory("BackgroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), SRDescription("BackgroundStyleDesc", "System.Workflow.ComponentModel.Design.DesignerResources"), DispId(7)> _
        Public Overridable Property BackgroundStyle As LinearGradientMode
            Get
                Return Me.backgroundStyle
            End Get
            Set(ByVal value As LinearGradientMode)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                Me.backgroundStyle = value
                If (Not Me.backgroundBrush Is Nothing) Then
                    Me.backgroundBrush.Dispose
                    Me.backgroundBrush = Nothing
                End If
            End Set
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property BoldFont As Font
            Get
                Return MyBase.ContainingTheme.AmbientTheme.BoldFont
            End Get
        End Property

        <DispId(3), TypeConverter(GetType(ColorPickerConverter)), SRCategory("ForegroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), Editor(GetType(ColorPickerEditor), GetType(UITypeEditor)), SRDescription("BorderColorDesc", "System.Workflow.ComponentModel.Design.DesignerResources")> _
        Public Overridable Property BorderColor As Color
            Get
                Return Me.borderColor
            End Get
            Set(ByVal value As Color)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                Me.borderColor = value
                If (Not Me.borderPen Is Nothing) Then
                    Me.borderPen.Dispose
                    Me.borderPen = Nothing
                End If
            End Set
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property BorderPen As Pen
            Get
                If (Me.borderPen Is Nothing) Then
                    Me.borderPen = New Pen(Me.borderColor, CSng(Me.BorderWidth))
                    Me.borderPen.DashStyle = Me.borderStyle
                End If
                Return Me.borderPen
            End Get
        End Property

        <SRCategory("ForegroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), TypeConverter(GetType(FilteredEnumConverter)), DispId(4), SRDescription("BorderStyleDesc", "System.Workflow.ComponentModel.Design.DesignerResources")> _
        Public Overridable Property BorderStyle As DashStyle
            Get
                Return Me.borderStyle
            End Get
            Set(ByVal value As DashStyle)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                If (value = DashStyle.Custom) Then
                    Throw New Exception(DR.GetString("CustomStyleNotSupported", New Object(0  - 1) {}))
                End If
                Me.borderStyle = value
                If (Not Me.borderPen Is Nothing) Then
                    Me.borderPen.Dispose
                    Me.borderPen = Nothing
                End If
            End Set
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property BorderWidth As Integer
            Get
                Return MyBase.ContainingTheme.AmbientTheme.BorderWidth
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property DesignerGeometry As DesignerGeometry
            Get
                If MyBase.ContainingTheme.AmbientTheme.DrawRounded Then
                    Return DesignerGeometry.RoundedRectangle
                End If
                Return DesignerGeometry.Rectangle
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property DesignerImage As Image
            Get
                If ((Me.designerImage Is Nothing) AndAlso (Me.designerImagePath.Length > 0)) Then
                    Me.designerImage = DesignerHelpers.GetImageFromPath(Me, MyBase.ContainingTheme.ContainingFileDirectory, Me.designerImagePath)
                End If
                Return Me.designerImage
            End Get
        End Property

        <Editor(GetType(ImageBrowserEditor), GetType(UITypeEditor)), SRDescription("ImageDesc", "System.Workflow.ComponentModel.Design.DesignerResources"), SRCategory("ForegroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), DispId(1)> _
        Public Overridable Property DesignerImagePath As String
            Get
                Return Me.designerImagePath
            End Get
            Set(ByVal value As String)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                If (((Not value Is Nothing) AndAlso (value.Length > 0)) AndAlso (value.Contains(Path.DirectorySeparatorChar.ToString) AndAlso Path.IsPathRooted(value))) Then
                    value = DesignerHelpers.GetRelativePath(MyBase.ContainingTheme.ContainingFileDirectory, value)
                    If Not DesignerHelpers.IsValidImageResource(Me, MyBase.ContainingTheme.ContainingFileDirectory, value) Then
                        Throw New InvalidOperationException(DR.GetString("Error_InvalidImageResource", New Object(0  - 1) {}))
                    End If
                End If
                Me.designerImagePath = value
                If (Not Me.designerImage Is Nothing) Then
                    Me.designerImage.Dispose
                    Me.designerImage = Nothing
                End If
            End Set
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property Font As Font
            Get
                Return MyBase.ContainingTheme.AmbientTheme.Font
            End Get
        End Property

        <SRDescription("ForeColorDesc", "System.Workflow.ComponentModel.Design.DesignerResources"), SRCategory("ForegroundCategory", "System.Workflow.ComponentModel.Design.DesignerResources"), TypeConverter(GetType(ColorPickerConverter)), DispId(2), Editor(GetType(ColorPickerEditor), GetType(UITypeEditor))> _
        Public Overridable Property ForeColor As Color
            Get
                Return Me.foreColor
            End Get
            Set(ByVal value As Color)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly", New Object(0  - 1) {}))
                End If
                Me.foreColor = value
                If (Not Me.foregroundPen Is Nothing) Then
                    Me.foregroundPen.Dispose
                    Me.foregroundPen = Nothing
                End If
                If (Not Me.foregroundBrush Is Nothing) Then
                    Me.foregroundBrush.Dispose
                    Me.foregroundBrush = Nothing
                End If
            End Set
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property ForegroundBrush As Brush
            Get
                If (Me.foregroundBrush Is Nothing) Then
                    Me.foregroundBrush = New SolidBrush(Me.foreColor)
                End If
                Return Me.foregroundBrush
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property ForegroundPen As Pen
            Get
                If (Me.foregroundPen Is Nothing) Then
                    Me.foregroundPen = New Pen(Me.foreColor, CSng(Me.BorderWidth))
                End If
                Return Me.foregroundPen
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property ImageSize As Size
            Get
                Return ActivityDesignerTheme.ImageSizes(CInt(MyBase.ContainingTheme.AmbientTheme.DesignerSize))
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
        Public ReadOnly Property Size As Size
            Get
                Return ActivityDesignerTheme.DesignerSizes(CInt(MyBase.ContainingTheme.AmbientTheme.DesignerSize))
            End Get
        End Property


        ' Fields
        Private backColorEnd As Color
        Private backColorStart As Color
        Private backgroundBrush As Brush
        Private backgroundBrushRect As Rectangle
        Private backgroundStyle As LinearGradientMode
        Private borderColor As Color
        Private borderPen As Pen
        Private borderStyle As DashStyle
        Private designerImage As Image
        Private designerImagePath As String
        Private Shared ReadOnly DesignerSizes As Size() = New Size() { New Size(90, 40), New Size(130, &H29), New Size(110, 50) }
        Private foreColor As Color
        Private foregroundBrush As Brush
        Private foregroundPen As Pen
        Private Shared ReadOnly ImageSizes As Size() = New Size() { New Size(&H10, &H10), New Size(&H10, &H10), New Size(&H18, &H18) }
    End Class
End Namespace

